package middleware

import (
	"gin_server/uitl/response"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"strings"
	"time"
)

var (
	getjwtKey = viper.GetString("token.key")
	jwtKey    = []byte(getjwtKey)
)

// 设置claims
type MyClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

// 生成token
func SetToken(username string) (string, int) {

	// 设置过期时间
	expireTime := time.Now().Add(10 * time.Hour)

	SetClaims := MyClaims{
		Username: username,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(),
			Issuer:    "ginserve",
		},
	}

	reqClaim := jwt.NewWithClaims(jwt.SigningMethodHS256, SetClaims)
	token, err := reqClaim.SignedString(jwtKey)

	if err != nil {
		return "", response.ERROR
	}
	return token, response.SUCCESS
}

// 验证token
func CheckToken(token string) (*MyClaims, int) {
	setToken, _ := jwt.ParseWithClaims(token, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
		return jwtKey, nil
	})
	if key, _ := setToken.Claims.(*MyClaims); setToken.Valid {
		return key, response.SUCCESS
	} else {
		return nil, response.ERROR
	}
}

// 生成中间件
func JwtToken() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 获取 Authorization
		tokenHeader := c.GetHeader("Authorization")
		if tokenHeader == "" || !strings.HasPrefix(tokenHeader, "Bearer") {
			response.ResErr(c, 401, "token不存在或格式不正确")
			c.Abort()
			return
		}

		tokenString := strings.SplitN(tokenHeader, " ", 2)
		key, tokenCode := CheckToken(tokenString[1])
		if tokenCode == response.ERROR {
			response.ResErr(c, 401, "token无效")
			c.Abort()
			return
		}
		if time.Now().Unix() > key.ExpiresAt {
			response.ResErr(c, 401, "token已过期")
			c.Abort()
			return
		}
		c.Set("username", key.Username)
		c.Next()
	}
}
